package com.darkidiot.session;

import com.darkidiot.session.IDGenerator.DefaultSessionIdGenerator;
import com.darkidiot.session.IDGenerator.SessionIdGenerator;
import com.darkidiot.session.conf.Configuration;
import com.darkidiot.session.redis.RedisSessionSource;
import com.darkidiot.session.redis.SessionSource;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * 分布式session manager类
 * session attribute持久化到redis
 * Copyright (c) for darkidiot
 * Date:2017/4/14
 * Author: <a href="darkidiot@icloud.com">darkidiot</a>
 * School: CUIT
 * Desc:
 */
@Slf4j
final class DistributedSessionManager implements SessionSource {
    private SessionSource dataSource;
    @Getter
    private final SessionIdGenerator sessionIdGenerator;
    @Getter
    private static Configuration configuration = null;

    private DistributedSessionManager(Configuration configuration) {
        this.sessionIdGenerator = new DefaultSessionIdGenerator();
        DistributedSessionManager.configuration = configuration;
        if ("redis".equals(configuration.getSource())) {
            this.dataSource = new RedisSessionSource(configuration);
        } else {
            throw new IllegalStateException("Constructor error: not supported source type : " + configuration.getSource());
        }
    }

    static DistributedSessionManager newInstance(Configuration configuration) {
        DistributedSessionManager.configuration = configuration;
        return DistributedSessionManager.SingletonHolder.INSTANCE;
    }

    static DistributedSessionManager getInstance() {
        return DistributedSessionManager.SingletonHolder.INSTANCE;
    }

    @Override
    public Map<String, Object> findAttributeByMsid(String id) {
        return dataSource.findAttributeByMsid(id);
    }

    @Override
    public boolean refreshExpireTime(String msid, int maxInactiveInterval) {
        return dataSource.refreshExpireTime(msid, maxInactiveInterval);
    }

    @Override
    public boolean deletePhysically(String id) {
        return dataSource.deletePhysically(id);
    }

    @Override
    public boolean save(String id, Map<String, Object> snapshot, int maxInactiveInterval) {
        return dataSource.save(id, snapshot, maxInactiveInterval);
    }

    @Override
    public void destroy() {
        dataSource.destroy();
    }

    private static final class SingletonHolder {
        private static final DistributedSessionManager INSTANCE = init();

        private static DistributedSessionManager init() {
            return new DistributedSessionManager(DistributedSessionManager.configuration);
        }

        private SingletonHolder() {
        }

    }
}
